<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // // 向量类型
        // class Vec {
        //     constructor(x, y) {
        //         this.x = x
        //         this.y = y
        //     }

        //     plus(i) {
        //         return new Vec(this.x + i.x, this.y + i.y)
        //     }
        //     minus(o) {
        //         return new Vec(this.x - o.x, this.y - o.y)
        //     }

        //     get length() {
        //         return Math.sqrt(this.x * this.x + this.y * this.y)
        //     }
        // }


        // console.log(new Vec(1, 2).plus(new Vec(2, 3))); // → Vec{x: 3, y: 5}
        // console.log(new Vec(1, 2).minus(new Vec(2, 3))); // → Vec{x: -1, y: -1}
        // console.log(new Vec(3, 4).length); // → 5


        // // 分组
        // class Group {
        //     constructor() {
        //         this.as = []
        //     }
        //     add(value) {
        //         if (!this.has(value)) {
        //             this.as.push(value);
        //         }
        //     }

        //     delete(value) {
        //         this.as = this.as.filter(v => v != value);
        //     }

        //     has(value) {
        //         return this.as.includes(value);
        //     }

        //     static from(arrays) {
        //         let group = new Group;
        //         for (let value of arrays) {
        //             group.add(value);
        //         }
        //         return group;
        //     }
        // }
        // let group = Group.from([10, 20]);
        // console.log(group.has(10));// → true
        // console.log(group.has(30));// → false
        // group.add(10);
        // group.delete(10);
        // console.log(group.has(10));// → false

        // 可迭代分组
        class Group {
            constructor() {
                this.members = [];
            }

            add(value) {
                if (!this.has(value)) {
                    this.members.push(value);
                }
            }

            delete(value) {
                this.members = this.members.filter(v => v != value);
            }

            has(value) {
                return this.members.includes(value);
            }

            static from(collection) {
                let group = new Group;
                for (let value of collection) {
                    group.add(value);
                }
                return group;
            }

            [Symbol.iterator]() {
                return new GroupIterator(this);
            }
        }

        class GroupIterator {
            constructor(group) {
                this.group = group;
                this.position = 0;
            }

            next() {
                if (this.position >= this.group.members.length) {
                    return { done: true };
                } else {
                    let result = {
                        value: this.group.members[this.position],
                        done: false
                    };
                    this.position++;
                    return result;
                }
            }
        }
        for (let value of Group.from(["a", "b", "c"])) {
            console.log(value);
        }
        // → a
        // → b
        // → c
    </script>
</body>

</html>